﻿/*
 * @(#)DB.cs, 2010-5-4 16:38:10.
 *
 * @author fengxianwen.
 *
 *
 */
using System;
using System.Data;
using System.Data.Common;
using JKF.Substructure.Properties;
using JKF.Substructure;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace JKF.Substructure
{
    /// <summary>
    /// 数据库实例相关的静态属性和方法。
    /// </summary>
    public static class DB
    {
        /// <summary>
        /// 获取数据库实例。
        /// </summary>
        public static Database HR
        {
            get
            {
                string aa = Resources.Name_ConnString;
                return DatabaseFactory.CreateDatabase(Resources.Name_ConnString);
            }
        }

        public static Alx.ORM.Core.ObjectContext Platform
        {
            get
            {
                var cnnstr = System.Configuration.ConfigurationManager.ConnectionStrings["hrConnection"].ConnectionString;
                return new Alx.ORM.Core.ObjectContext(cnnstr);
            }
        }

        public static Database HIS(string regionCode)
        {

            return DatabaseFactory.CreateDatabase("HisConnection_" + regionCode);

        }

        public static Database NH(string regionCode)
        {

            return DatabaseFactory.CreateDatabase("NHConnection_" + regionCode);

        }

        /// <summary>
        /// 获取数据库服务器的当前时间。
        /// </summary>
        public static DateTime GetNow(this Database db)
        {
            //return DateTime.Now;
            using (IDataReader reader = db.ExecuteReader(CommandType.Text, Resources.Sql_QueryNow))
            {
                reader.Read();
                return reader.GetDateTime(0);
            }
        }

        /// <summary>
        /// 获取数据库全球唯一id,比系统自动生成的速度快
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public static string GetNewGuid(this Database db)
        {
            using (IDataReader reader = db.ExecuteReader(CommandType.Text, "select (CONVERT([uniqueidentifier],CONVERT([binary](10),newid(),(0))+CONVERT([binary](6),getdate(),(0)),(0)))"))
            {
                reader.Read();
                return reader.GetGuid(0).ToString();
            }
        }

        public static TransactionHR BeginTransactionHR()
        {
            return new TransactionHR();
        }

        public static TransactionHR BeginTransactionHR(IsolationLevel il)
        {
            return new TransactionHR(il);
        }
    }

    public sealed class TransactionHR : IDisposable
    {
        private DbConnection conn = null;
        private DbTransaction Transaction { get; set; }
        public Database CurrentDB { get; set; }

        private bool commited = false;
        private bool rollbacked = false;

        internal TransactionHR() : this(IsolationLevel.Serializable) { }

        internal TransactionHR(IsolationLevel il)
        {
            this.CurrentDB = DB.HR;
            this.conn = this.CurrentDB.CreateConnection();
            this.conn.Open();
            this.Transaction = conn.BeginTransaction(il);
        }

        public void Commit()
        {
            if (this.commited || this.rollbacked) return;

            try
            {
                this.Transaction.Commit();
            }
            catch (InvalidOperationException) { }

            this.commited = true;

            //this.conn.Close();
        }

        public void Rollback()
        {
            if (this.rollbacked || this.commited) return;

            try
            {
                this.Transaction.Rollback();
            }
            catch (InvalidOperationException) { }

            this.rollbacked = true;

            //this.conn.Close();
        }

        private void prepare()
        {
            if (this.conn == null)
            {
                throw new Exception("无数据库连接");
            }

            if (this.Transaction == null)
            {
                throw new Exception("事务为空");
            }
        }

        public DataSet ExecuteDataSet(string sql)
        {
            this.prepare();
            return this.CurrentDB.ExecuteDataSet(this.Transaction, CommandType.Text, sql);
        }

        

        public object ExecuteScalar(string sql)
        {
            this.prepare();
            return this.CurrentDB.ExecuteScalar(this.Transaction, CommandType.Text, sql);
        }

        public object ExecuteScalar(DbCommand command)
        {
            this.prepare();
            return this.CurrentDB.ExecuteScalar(command, this.Transaction);
        }

        public object ExecuteScalar(string storedProcedureName, params object[] parameterValues)
        {
            this.prepare();
            return this.CurrentDB.ExecuteScalar(this.Transaction, storedProcedureName, parameterValues);
        }

        public DataSet ExecuteDataSet(DbCommand command)
        {
            this.prepare();
            return this.CurrentDB.ExecuteDataSet(command, this.Transaction);
        }



        public DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
        {
            this.prepare();
            return this.CurrentDB.ExecuteDataSet(this.Transaction, storedProcedureName, parameterValues);
        }

        public int ExecuteNonQuery(string sql)
        {
            this.prepare();
            return this.CurrentDB.ExecuteNonQuery(this.Transaction, CommandType.Text, sql);
        }

        public int ExecuteNonQuery(DbCommand command)
        {
            this.prepare();
            return this.CurrentDB.ExecuteNonQuery(command, this.Transaction);
        }

        public int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)
        {
            this.prepare();
            return this.CurrentDB.ExecuteNonQuery(this.Transaction, storedProcedureName, parameterValues);
        }

        #region IDisposable 成员

        public void Dispose()
        {
            if (!this.commited && !this.rollbacked)
            {
                this.Commit();
            }

            this.Transaction.Dispose();

            GC.SuppressFinalize(this);

            //try
            //{
            //    this.conn.Dispose();
            //}
            //catch { }
        }

        #endregion
    }
}
